package com.whfc.common.third.map.impl;

import com.alibaba.fastjson.JSONObject;
import com.whfc.common.third.map.MapApi;
import com.whfc.common.third.map.MapLoc;
import com.whfc.common.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.MessageFormat;
import java.util.List;

/**
 * @Description: 腾讯地图API
 * @author: xugcheng
 * @version: 1.0
 * @date: 2021-10-13 10:47
 */
public class QQMapApi implements MapApi {

    private static Logger logger = LoggerFactory.getLogger(QQMapApi.class);

    private static final String translateUrlPattern = "https://apis.map.qq.com/ws/coord/v1/translate?key={0}&locations={1}&output=JSON&type={2}&sig={3}";

    private static final String translateSignParamPattern = "/ws/coord/v1/translate?key={0}&locations={1}&output=JSON&type={2}{3}";

    private static final String geocoderUrl = "https://apis.map.qq.com/ws/geocoder/v1?key={0}&location={1}&sig={2}";

    private static final String geocoderSignUrl = "/ws/geocoder/v1?key={0}&location={1}{2}";

    private static final Integer locationTypeGps = 1;

    private static final Integer success = 0;


    /**
     * key
     */
    private String qqMapKey;

    /**
     * sk
     */
    private String qqMapSk;

    public QQMapApi() {
    }

    public QQMapApi(String qqMapKey, String qqMapSk) {
        this.qqMapKey = qqMapKey;
        this.qqMapSk = qqMapSk;
    }

    public String getQqMapKey() {
        return qqMapKey;
    }

    public void setQqMapKey(String qqMapKey) {
        this.qqMapKey = qqMapKey;
    }

    public String getQqMapSk() {
        return qqMapSk;
    }

    public void setQqMapSk(String qqMapSk) {
        this.qqMapSk = qqMapSk;
    }

    @Override
    public Gps translateToGcj02(Double lngWgs84, Double latWgs84) {
        //gps坐标系转换(wgs84->gcj02)
        if (lngWgs84 > 0 && latWgs84 > 0) {
            Gps gpsWgs84 = new Gps(latWgs84, lngWgs84);
            Gps gps = translateToGcj02(gpsWgs84);
            if (gps == null) {
                gps = PositionUtil.gps84_To_Gcj02(latWgs84, lngWgs84);
            }
            if (gps != null) {
                return gps;
            }
        }
        return new Gps(latWgs84, lngWgs84);
    }

    @Override
    public MapLoc geocode(Double lng, Double lat) {
        if (lat == null || lng == null) {
            return null;
        }
        MapLoc mapLoc = new MapLoc();
        String locations = lat + "," + lng;
        try {
            // 获取签名
            String sign = MD5Util.md5Encode(MessageFormat.format(geocoderSignUrl, qqMapKey, locations, qqMapSk));
            String translateUrl = MessageFormat.format(geocoderUrl, qqMapKey, locations, sign);
            String response = HttpUtil.doGet(translateUrl);
            //logger.info("坐标转换地址,request{},response:{}", translateUrl, response);
            JSONObject jsonObject = JSONObject.parseObject(response);
            Integer status = jsonObject.getInteger("status");
            if (status == 0) {
                JSONObject result = jsonObject.getJSONObject("result");
                String address = result.getString("address");
                JSONObject addressComponent = result.getJSONObject("address_component");
                mapLoc.setAddress(address);
                mapLoc.setNation(addressComponent.getString("nation"));
                mapLoc.setProvince(addressComponent.getString("province"));
                mapLoc.setCity(addressComponent.getString("city"));
                mapLoc.setDistrict(addressComponent.getString("district"));
                mapLoc.setStreet(addressComponent.getString("street"));
                mapLoc.setStreetNumber(addressComponent.getString("street_number"));
            }
        } catch (Exception e) {
            logger.warn("坐标转地址失败：{}", e.getMessage());
        }
        return mapLoc;
    }


    /**
     * 单个坐标转换
     *
     * @param wgs84Location
     * @return
     */
    private Gps translateToGcj02(Gps wgs84Location) {

        StringBuffer locations = new StringBuffer();
        locations.append(wgs84Location.getLat())
                .append(",")
                .append(wgs84Location.getLng());
        QQMapResult result = this.translate(locations.toString());
        if (result != null && success.equals(result.getStatus())) {
            List<Gps> gpsList = result.getLocations();
            if (gpsList.size() > 0) {
                return gpsList.get(0);
            }
        }
        return null;
    }

    /**
     * 批量坐标转换
     *
     * @param locations
     * @return
     */
    private QQMapResult translate(String locations) {
        Integer type = locationTypeGps;
        String sign = sign(qqMapKey, locations, type, qqMapSk);
        String translateUrl = MessageFormat.format(translateUrlPattern, qqMapKey, locations, type, sign);
        String response = HttpUtil.doGet(translateUrl);
        //logger.info("坐标转换,request:{},response:{}", translateUrl, response);
        QQMapResult result = JSONUtil.parseObject(response, QQMapResult.class);
        return result;
    }

    /**
     * 签名
     *
     * @param key
     * @param locations
     * @param type
     * @param sk
     * @return
     */
    private String sign(String key, String locations, Integer type, String sk) {
        String signParam = MessageFormat.format(translateSignParamPattern, qqMapKey, locations, type, sk);
        return MD5Util.md5Encode(signParam);
    }
}
